﻿using System.Diagnostics;

namespace DGMResourcesTool.Logic.P4Util
{
    public class P4Shell
    {
        static Process process_;

        public static void Log(string fmt, params object[] args)
        {
            string msg = string.Format(fmt, args);
        }

        public static void LogError(string fmt, params object[] args)
        {
            string msg = string.Format(fmt, args);
        }

        public static void Init(string userName, string password, string port, string workingSet, bool standardoutput = true, bool standarderror = true)
        {
            process_ = new Process();
            process_.StartInfo.UseShellExecute = false;
            process_.StartInfo.RedirectStandardOutput = standardoutput;
            process_.StartInfo.RedirectStandardError = standarderror;

            process_.StartInfo.EnvironmentVariables.Add("P4PORT", port);
            process_.StartInfo.EnvironmentVariables.Add("P4CLIENT", workingSet);

            if (userName.Length != 0 && password.Length != 0)
            {
                process_.StartInfo.EnvironmentVariables.Add("P4USER", userName);
                process_.StartInfo.EnvironmentVariables.Add("P4PASSWD", password);
            }

#if UNITY_EDITOR_OSX
		string p4File = System.IO.Path.GetFullPath( "../mac/p4");
		process_.StartInfo.FileName =p4File;
#else
            process_.StartInfo.FileName = "p4";
#endif
            process_.StartInfo.CreateNoWindow = true;
        }


        public static void Add(string path)
        {
            process_.StartInfo.Arguments = "add " + path;
            process_.Start();

            process_.WaitForExit();
            HandleOutput();
            process_.Close();
        }

        public static void Delete(string path)
        {
            process_.StartInfo.Arguments = "delete -v " + path;
            process_.Start();
            process_.WaitForExit();
            HandleOutput();

            process_.Close();
        }

        public static void Delete2(string path)
        {
            process_.StartInfo.Arguments = "delete -v " + path;
            process_.Start();
            while (!process_.WaitForExit(1000)) ;
            HandleOutput();
            process_.Close();
        }

        public static void SubmitAllChange(string description = "")
        {
            process_.StartInfo.Arguments = "submit -f \"" + description + "\" submitunchanged -i";
            process_.Start();
            process_.WaitForExit();
            HandleOutput();
            process_.Close();
        }


        public static void Checkout(string path, bool handleOutput = true)
        {
            process_.StartInfo.Arguments = "edit " + path;
            process_.Start();
            process_.WaitForExit();
            if (handleOutput)
            {
                HandleOutput();
            }
            process_.Close();
        }

        public static void Revert(string path, bool handleOutput = true)
        {
            process_.StartInfo.Arguments = "revert " + path;
            process_.Start();
            process_.WaitForExit();
            if (handleOutput)
            {
                HandleOutput();
            }

            process_.Close();
        }

        public static void RevertIfUnChanged(string path, bool handleOutput = true)
        {
            process_.StartInfo.Arguments = "revert -a " + path;
            process_.Start();
            process_.WaitForExit();
            if (handleOutput)
            {
                HandleOutput();
            }
            process_.Close();
        }

        public static void Sync(string path, bool forced = false)
        {
            process_.StartInfo.Arguments = "sync ";
            if (forced)
            {
                process_.StartInfo.Arguments += "-f ";
            }
            process_.StartInfo.Arguments += path;

            process_.Start();
            process_.WaitForExit();
            HandleOutput();

            process_.Close();
        }

        public static bool checkStatus(string path)
        {
            process_.StartInfo.Arguments = "sync -f ";
            process_.StartInfo.Arguments += path;
            process_.Start();
            while (!process_.WaitForExit(1000)) ;

            HandleOutput();
            return process_.ExitCode == 0;
        }

        public static bool Sync2(string path, bool forced = false)
        {
            process_.StartInfo.Arguments = "sync ";
            if (forced)
            {
                process_.StartInfo.Arguments += "-f ";
            }
            process_.StartInfo.Arguments += path;

            process_.Start();
            while (!process_.WaitForExit(1000)) ;
            HandleOutput();

            return process_.ExitCode == 0;
        }

        public static bool Checkout2(string path)
        {
            process_.StartInfo.Arguments = "edit " + path;
            process_.Start();
            while (!process_.WaitForExit(1000)) ;

            HandleOutput();
            return process_.ExitCode == 0;
        }

        public static bool Submit2(string path, string description = "empty")
        {
            process_.StartInfo.Arguments = "submit ";
            process_.StartInfo.Arguments += "-d ";
            process_.StartInfo.Arguments += "\"" + description + "\" ";
            process_.StartInfo.Arguments += path;
            process_.Start();
            while (!process_.WaitForExit(1000)) ;

            HandleOutput();
            return process_.ExitCode == 0;
        }

        public static void Reconcile(string path, bool add = true, bool edit = true, bool del = true)
        {
            process_.StartInfo.Arguments = "reconcile ";
            if (add)
            {
                process_.StartInfo.Arguments += "-a ";
            }
            if (edit)
            {
                process_.StartInfo.Arguments += "-e ";
            }
            if (del)
            {
                process_.StartInfo.Arguments += "-d ";
            }
            process_.StartInfo.Arguments += path;

            //Log(process_.StartInfo.Arguments);

            process_.Start();
            process_.WaitForExit();
            HandleOutput();

            process_.Close();
        }


        public static void Submit(string path, string description = "empty")
        {
            process_.StartInfo.Arguments = "submit ";
            process_.StartInfo.Arguments += "-d ";
            process_.StartInfo.Arguments += "\"" + description + "\" ";
            process_.StartInfo.Arguments += path;
            process_.Start();
            process_.WaitForExit();
            HandleOutput();
            process_.Close();
        }

        public static void Update(string path)
        {
            process_.StartInfo.Arguments = "sync ";
            //            path = path.Replace(@"\", "\");
            process_.StartInfo.Arguments += path;
            process_.StartInfo.Arguments += "#head";

            process_.Start();
            process_.WaitForExit();
            HandleOutput();

            process_.Close();
        }

        public static string OpenedInfo(string path = "")
        {
            process_.StartInfo.Arguments = "opened " + path;
            process_.Start();
            process_.WaitForExit();

            string info = string.Empty;
            if (process_.ExitCode != 0)
            {
                string error = process_.StandardError.ReadToEnd();
                LogError(error);
            }
            else
            {
                info = process_.StandardOutput.ReadToEnd();
            }

            process_.Close();

            return info;
        }
        public static int Sync_Multiple(string path, bool forced = false)
        {
            int exit_code = 0;
            process_.StartInfo.Arguments = "sync ";
            if (forced)
            {
                process_.StartInfo.Arguments += "-f ";
            }
            process_.StartInfo.Arguments += path;
            //UnityEngine.Debug.Log(process_.StartInfo.Arguments);
            process_.Start();
            process_.WaitForExit();
            exit_code = process_.ExitCode;
            process_.Close();
            return exit_code;
        }

        public static void HandleOutput()
        {
            if (process_.ExitCode != 0)
            {
                if (process_.StartInfo.RedirectStandardError)
                {
                    string error = process_.StandardError.ReadToEnd();
                    LogUtility.AddToLog(error);
                }

            }
            else
            {
                if (process_.StartInfo.RedirectStandardOutput)
                {
                    string output = process_.StandardOutput.ReadToEnd();
                    LogUtility.AddToLog(output);
                }

            }
        }
    }
}